﻿using Modbus.Device;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace ModbusProgram
{
    internal class Program
    {
        
        
        static void Main(string[] args)
        {
            TestReadString();
        }

        static void TestReadFloat() {
            SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
            IModbusMaster master = ModbusSerialMaster.CreateRtu(serialPort);
            if (!serialPort.IsOpen) {
                serialPort.Open();
            }
            ushort[] datas=master.ReadHoldingRegisters(1, 0, 2);
            //Array.Reverse(datas);
            byte[] dataBytes= Ushorts2Bytes(datas);
            Console.WriteLine(BitConverter.ToSingle(dataBytes,0));
            Console.ReadKey();
            serialPort.Close();
            serialPort.Dispose();
        }

        static void TestWriteFloat(float data) {
            SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
            IModbusMaster master = ModbusSerialMaster.CreateRtu(serialPort);
            if (!serialPort.IsOpen)
            {
                serialPort.Open();
            }
            byte[] dataBytes= BitConverter.GetBytes(data);
            ushort[] shortData= Bytes2Ushorts(dataBytes);
            master.WriteMultipleRegisters(1, 0, shortData);
        }
        static void TestWriteBool() {
            SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
            IModbusMaster master = ModbusSerialMaster.CreateRtu(serialPort);
            if (!serialPort.IsOpen)
            {
                serialPort.Open();
            }
            master.WriteSingleCoil(1, 0, false);
        }

        static void TestWriteString(string text) {
            SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
            IModbusMaster master = ModbusSerialMaster.CreateRtu(serialPort);
            if (!serialPort.IsOpen)
            {
                serialPort.Open();
            }
            byte[] bytesTemp = Encoding.UTF8.GetBytes(text);
            ushort[] dest = Bytes2Ushorts(bytesTemp);
            master.WriteMultipleRegisters(1,0, dest);
        }

        static void TestReadString() {
            SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
            IModbusMaster master = ModbusSerialMaster.CreateRtu(serialPort);
            if (!serialPort.IsOpen)
            {
                serialPort.Open();
            }
            ushort[] data=master.ReadHoldingRegisters(1, 0, 3);
            byte[] dataByte= Ushorts2Bytes(data);
            Console.WriteLine(Encoding.UTF8.GetString(dataByte).Trim());
            Console.ReadKey();
        }
        private static byte[] Ushorts2Bytes(ushort[] src, bool reverse = false)
        {

            int count = src.Length;
            byte[] dest = new byte[count << 1];
            if (reverse)
            {
                for (int i = 0; i < count; i++)
                {
                    dest[i * 2] = (byte)(src[i] >> 8);
                    dest[i * 2 + 1] = (byte)(src[i] >> 0);
                }
            }
            else
            {
                for (int i = 0; i < count; i++)
                {
                    dest[i * 2] = (byte)(src[i] >> 0);
                    dest[i * 2 + 1] = (byte)(src[i] >> 8);
                }
            }
            return dest;
        }

        private static ushort[] Bytes2Ushorts(byte[] src, bool reverse = false)
        {
            int len = src.Length;

            byte[] srcPlus = new byte[len + 1];
            src.CopyTo(srcPlus, 0);
            int count = len >> 1;

            if (len % 2 != 0)
            {
                count += 1;
            }

            ushort[] dest = new ushort[count];
            if (reverse)
            {
                for (int i = 0; i < count; i++)
                {
                    dest[i] = (ushort)(srcPlus[i * 2] << 8 | srcPlus[2 * i + 1] & 0xff);
                }
            }
            else
            {
                for (int i = 0; i < count; i++)
                {
                    dest[i] = (ushort)(srcPlus[i * 2] & 0xff | srcPlus[2 * i + 1] << 8);
                }
            }

            return dest;
        }
    }
}
